<!--
 * @Description: 
 * @Version: 2.0
 * @Autor: swc
 * @Date: 2024-09-07 17:12:46
 * @LastEditors: zss
 * @LastEditTime: 2024-11-02 10:39:23
-->
<template>
  <div class="init-container">
    <div class="mask-container" v-if="isMask"></div>
    <div class="main-content">
      <div class="main-left">
        <div class="main-left-top">
          <Collapse v-model="currPanelVal">
            <Panel :name="item.id" v-for="(item, index) of ecArr" :key="index">
              {{ $srv.getI18nBySrv(item.title) + '[' + item.ecCode + ']' }}

              <div slot="content" class="ec-box-det">
                <div
                  class="ec-box-det-item"
                  v-for="(itm, idx) of item.ecBoxDet"
                  :key="idx"
                >
                  <span
                    class="ec-box-det-item-title"
                    :class="{ 'val-err': itm.err !== '' }"
                    @click="ecDetCodeClick(itm, idx, $event)"
                    >{{
                      $srv.getI18nBySrv(itm.title) + '[' + itm.code + ']'
                    }}</span
                  >
                  <span>:</span>
                  <span :title="itm.timestamp" class="ec-box-det-item-val">{{
                    itm.val
                  }}</span>
                </div>
              </div>
            </Panel>
          </Collapse>
        </div>
        <div class="main-left-bottom">
          <div id="echarts-container"></div>
        </div>
      </div>
      <div class="main-right">
        <div class="main-right-top">
          <vxe-grid
            ref="xGrid"
            v-bind="gridOptions"
            @page-change="pageChange"
          ></vxe-grid>
        </div>
        <div class="main-right-bottom">
          <Input
            v-model="errContent"
            type="textarea"
            autosize
            readonly
            :rows="10"
            :border="false"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import * as echarts from 'echarts';
import {
  I_cmd,
  N_cScadaView,
  T_cmd,
  T_srv,
  Tsrv,
  getGridOptions,
  ifs,
  vue
} from './config';

@T_srv.comp
export default class cScadaView extends vue {
  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  /* 组件名 */
  private name: string = 'cScadaView';

  private funName: string = 'cScadaView';

  private G_compName: string = this.name;

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  /* 指挥部 */
  private GT_command: I_cmd = new T_cmd();

  /* 遮罩 */
  public isMask: boolean = false;

  // 电控数据
  public ecArr: Array<N_cScadaView.I_ecBox> = [];

  public currPanelVal: string = '';

  public gridOptions = getGridOptions();

  private currentCLickCode: N_cScadaView.I_ecBoxDet;

  private myChart: echarts.ECharts;

  private errContent: string = '';

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command.init(this, this.GT_compBoxInfo);
    this.init();
  }

  mounted() {
    /* 向父组件发送实例 */
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    this.initEcharts();
  }

  destroyed() {
    // this.GT_command.stopTask();
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }

  private init() {
    this.funName = this.name; // 当前配置中的功能名
    this.getEcBoxDet();
  }

  /* 获取电控数据 */
  public getEcBoxDet() {
    Tsrv.standardPostReq<N_cScadaView.I_getEcBoxResp, any>(
      {},
      Tsrv.url.scadaGetEcBox
    ).then(([resp, err]) => {
      this.$msg(err ?? resp.msg);
      if (!resp.success) {
        this.ecArr = [];
        return;
      }
      this.GT_command.stopTask();
      this.GT_command.cleanEcBoxDetMap();
      resp.data.ecBox.forEach(ebox => {
        this.ecArr.push({
          id: ebox.id,
          ecCode: ebox.ecCode,
          title: ebox.title,
          model: ebox.model,
          protocol: ebox.protocol,
          ipAddr: ebox.ipAddr,
          port: ebox.port,
          type: ebox.type,
          ecBoxDet: []
        });
      });
      resp.data.driveParams.forEach(dps => {
        dps.forEach(ele => {
          for (let i = 0; i < this.ecArr.length; i++) {
            if (ele.ecBoxDet.ecBox.id === this.ecArr[i].id) {
              const det = {
                id: ele.ecBoxDet.id,
                code: ele.ecBoxDet.code,
                title: ele.ecBoxDet.title,
                dataType: ele.ecBoxDet.dataType,
                readWrite: ele.ecBoxDet.readWrite,
                val: '',
                err: '',
                timestamp: ''
              };
              this.ecArr[i].ecBoxDet.push(det);
              this.GT_command.setEcBoxDetMap(det.code, det);
              break;
            }
          }
        });
      });
      // this.GT_command.startTask();
      if (this.ecArr.length > 0) {
        this.currPanelVal = this.ecArr[0].id;
        this.ecDetCodeClick(this.ecArr[0].ecBoxDet[0]); // 默认点击第一个
      }
    });
  }

  /* 设置组件整体遮罩 */
  public setMask(p: boolean) {
    this.isMask = p;
  }

  public getMask(p: boolean): boolean {
    return this.isMask;
  }

  private initEcharts() {
    const chartDom = document.getElementById('echarts-container');
    this.myChart = echarts.init(chartDom);
  }

  private setEchartsData(
    xData: string[],
    yData: string[],
    type: 'value' | 'time'
  ) {
    const option = {
      tooltip: {
        trigger: 'axis',
        position(pt) {
          return [pt[0], '10%'];
        }
      },
      title: {
        left: 'center',
        text: Tsrv.getI18nBySrv(this.currentCLickCode?.title)
      },
      toolbox: {
        feature: {
          dataZoom: {
            yAxisIndex: 'none'
          },
          restore: {}
        }
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: xData
      },
      yAxis: {
        type,
        boundaryGap: [0, '100%']
      },
      dataZoom: [
        {
          type: 'inside',
          start: 0,
          end: 100
        },
        {
          start: 0,
          end: 100
        }
      ],
      series: [
        {
          type: 'line',
          symbol: 'none',
          sampling: 'lttb',
          itemStyle: {
            color: 'rgb(255, 70, 131)'
          },
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: 'rgb(255, 158, 68)'
              },
              {
                offset: 1,
                color: 'rgb(255, 70, 131)'
              }
            ])
          },
          data: yData
        }
      ]
    };

    option && this.myChart.setOption(option);
  }

  public ecDetCodeClick(itm: N_cScadaView.I_ecBoxDet, idx?: number, e?: any) {
    this.currentCLickCode = itm;
    this.GT_command.readDataOnce([itm.code]);
    const p = {
      ecCodes: [itm.code],
      beginTime: '2024-01-01 00:00:00',
      endTime: Tsrv.utils.getCurrentTimeStrCN(),
      pageNo: 1,
      pageSize: this.gridOptions.pagerConfig.pageSize
    };
    this.loadTableData(p);
  }

  /**
   * pageChange 翻页
   */
  private pageChange(e: any) {
    if (
      this.gridOptions.pagerConfig.currentPage !== e.currentPage ||
      this.gridOptions.pagerConfig.pageSize !== e.pageSize
    ) {
      this.gridOptions.pagerConfig.currentPage = e.currentPage;
      this.gridOptions.pagerConfig.pageSize = e.pageSize;
      const p: N_cScadaView.I_qryDataReq = {
        ecCodes: [this.currentCLickCode.code],
        beginTime: '2024-01-01 00:00:00',
        endTime: Tsrv.utils.getCurrentTimeStrCN(),
        pageNo: e.currentPage,
        pageSize: e.pageSize
      };
      this.loadTableData(p);
    }
  }

  public loadTableData(p: N_cScadaView.I_qryDataReq) {
    Tsrv.standardPostReq<N_cScadaView.I_qryDataResp, any>(
      p,
      Tsrv.url.scadaQueryData
    ).then(([resp, err]) => {
      if (err) {
        this.$msg(err);
        return;
      }
      if (!resp.success) {
        this.$msg(resp.msg);
        return;
      }
      const data = JSON.parse(wUnZipStr(resp.data));
      // const rowData = data[p.ecCodes[0]]?.d;
      const rowData = data[p.ecCodes[0]]?.d.map(it => ({
        ...it,
        t: new Date(it.t).toLocaleString()
      }));
      const total = data[p.ecCodes[0]]?.total;
      const recErrs = data[p.ecCodes[0]]?.recErrs;
      this.gridOptions.pagerConfig.total = total;
      const grid: any = this.$refs.xGrid;
      let type: 'value' | 'time' = 'value';
      grid.reloadData(rowData);
      this.setRecErrs(recErrs);
      if (!Tsrv.noValue(rowData)) {
        const timeData = rowData.map(it => it.t);
        // const timeData = rowData.map(it => new Date(it.t).toLocaleString());
        const valueData = rowData.map(it => {
          const t = typeof it.v;
          switch (t) {
            case 'boolean':
              type = 'value';
              return it.v ? 1 : 0;
            case 'number':
              type = 'value';
              return it.v;
            case 'string':
              if (!Tsrv.noValue(it.v)) {
                type = 'time';
                return new Date(it.v);
              }
              return it.v;
            default:
              return it.v;
          }
        });
        this.setEchartsData(timeData, valueData, type);
      } else {
        this.setEchartsData([], [], 'value');
      }
    });
  }

  public setRecErrs(recErrs: any) {
    if (
      Tsrv.noValue(recErrs) ||
      (Array.isArray(recErrs) && recErrs.length === 0)
    ) {
      return;
    }
    recErrs.forEach(ele => {
      this.errContent += `${ele?.time}->${ele?.err}\n`;
    });
  }
}
</script>
<style lang="scss" scoped>
.main-content {
  height: 100%;
  display: flex;
  flex-direction: row;
  .main-left {
    flex: 1;
    .main-left-top {
      width: 100%;
      height: 50%;
      ::v-deep .ivu-collapse {
        overflow: auto;
        height: 100%;
      }
      .ec-box-det {
        display: grid;
        // grid-template-columns: repeat(3, 1fr); /* 创建4列，每列宽度相等 */
        gap: 10px; /* 列与列之间的间隙 */
        padding: 10px; /* 容器内边距 */
        grid-template-columns: repeat(auto-fill, minmax(316px, 1fr));
        grid-gap: 10px; /* 网格项之间的间隙 */
        margin-left: 60px;
        margin-top: 2px;
        margin-bottom: 2px;
        margin-right: 2px;
        border: 1px solid #ccc;
        .ec-box-det-item {
          .ec-box-det-item-val {
            margin-left: 3px;
            border-bottom: 1px solid #ccc;
            color: rgb(72, 0, 255);
          }
          .ec-box-det-item-val:hover {
            cursor: help;
          }
          .ec-box-det-item-title {
            margin-right: 3px;
            font-weight: bold;
          }
          .ec-box-det-item-title:hover {
            cursor: pointer;
            background-color: #ccc;
          }
          .val-err {
            color: red;
          }
        }
      }
    }
    .main-left-bottom {
      border: 1px solid #ccc;
      width: 100%;
      height: 50%;
      overflow: auto;
      #echarts-container {
        width: 100%;
        height: 100%;
      }
    }
  }
  .main-right {
    border: 1px solid #ccc;
    width: 30%;
    .main-right-top {
      height: 70%;
      widows: 100%;
    }
    .main-right-bottom {
      border-top: 1px solid #ccc;
      height: 30%;
      widows: 100%;
    }
  }
}
</style>
